home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************************
- ITEMLIST
-
- Written by David Stroud 75165,421 11/13/93
-
- This module is a standalone, independent set of calls that provide
- an application a method to manage a last file loaded list facility.
- It uses a dynamically allocated list of filenames with which to
- manage the Windows menu calls. The module can be included in any
- application that requires managing 'last called' lists and is
- particularly useful when dealing with documents, files, and
- data sets.
-
- To initialize, ItemListInit must be called to set the following
- parameters:
-
- szDefaultDir = If you are using filenames, this is the name of the
- directory that will be trimmed out of the filename
- when it is added. This can be suppressed, and is
- ignored by passing a "" (zero length string).
-
- uMaxItems = The number of items to be stacked. Memory is allocated
- based on this value.
-
- uSubMenu = The sub menu to be appended to.
-
- Typical usage for a 'last file loaded':
-
- ItemListInit ("C:\MYDIR", 5, 0); // Inits memory and globals
- ItemListLoad ( GetMenu(hWndMain), "MY.INI");// Load element from the INI
- ....
- ItemListAdd ( GetMenu(hWndMain), "THISFILE.TXT"); // Add an element
- ....
- ....
- ItemListSave ( GetMenu(hWndMain), "MY.INI");// Save the elements to INI
- ItemListCleanup(); // Release memory/cleanup
-
-
- Remember, it is up to you to do the following:
-
- 1. Initialize...
- 2. Load defaults from your INI file...
- 3. Add items...they always 'rise to the top' avoiding explicit dups
- 4. Remove items...
- 5. Save defaults to your INI file
- 6. CLEAN UP MEMORY
-
- This module was written and compiled using Microsoft Visual C++ 1.0.
- ***************************************************************************/
-
- #include <windows.h>
- #include <ctype.h>
- #include <string.h>
- #include "itemlist.h"
-
- // Menu array tag
- typedef struct _itemtag {
- char szFile[ITEM_MAXLEN];
- } ITEMLIST;
-
- // Pointer to menu array
- typedef ITEMLIST FAR *LPITEMLIST;
-
- static HANDLE hMemITEM = NULL; // Handle to memory for alloc
- static LPITEMLIST lpitem; // Pointer to first element
- static char szDefaultDir[128]; // Default directory
- static UINT uMaxItems = 3; // Maximum number of menu items
- static UINT uSubMenu = 0; // Default menu is menu 0
-
- // Private prototype declarations
- UINT ItemListSet ( HMENU hMenu, LPSTR lpentry, UINT uItem );
- UINT ItemListFind (HMENU hMenu, LPSTR lpentry);
- VOID ItemListRestackMenu ( HMENU hMenu );
- VOID upcase(LPSTR lpszStr);
- UINT ItemListAddSeparator(HMENU hMenu);
- UINT ItemListRemoveSeparator (HMENU hMenu);
- BOOL ItemListHasSeparator (HMENU hMenu);
- VOID ItemListFilenameCleanup(LPSTR lpfile);
-
- /**********************************************************
- ItemListInit
-
- Initialize default directory, maximum number of
- items, and menu number. Allocate memory area based
- on the number of items allowed.
-
- Returns number allocated if successful, 0 if not
- **********************************************************/
- UINT ItemListInit (LPSTR lpdfdir, UINT uMax, UINT uMenu )
- {
- upcase(lpdfdir); // Force upper always
-
- if (uMax > ITEM_MAXFILES) // No more than predefined allowed
- uMax = ITEM_MAXFILES;
-
- // Initialize global static variables
- uMaxItems = uMax;
- uSubMenu = uMenu;
- lstrcpy ( szDefaultDir, lpdfdir );
-
- if ((hMemITEM = GlobalAlloc ( GHND, (DWORD)((uMax+1) * (DWORD)sizeof(ITEMLIST)))) == NULL)
- return 0;
-
- if ((lpitem = (LPITEMLIST)GlobalLock ( hMemITEM ))==NULL)
- return 0;
-
- return uMax;
- }
-
- /**********************************************************
- ItemListCleanup
-
- Release memory. Always returns 1.
-
- **********************************************************/
- UINT ItemListCleanup(VOID)
- {
- GlobalUnlock (hMemITEM);
- GlobalFree (hMemITEM);
- return 1;
- }
-
- /**********************************************************
- ItemListLoad
-
- Loads the file keys from the ini filename that is
- passed. Initializes the menu after the load occurs.
-
- Returns number of items attached to the sub menu
-
- **********************************************************/
- UINT ItemListLoad (HMENU hMenu, LPSTR lpinifile )
- {
- UINT uCount = 0;
- UINT i;
- char szKey[20];
- char szTemp[ITEM_MAXLEN];
-
- // If the user forgot to initialize, then we do that
- // for them here using the number of defaults declared
- // for the global statics
- if (hMemITEM == NULL)
- ItemListInit ("\\",uMaxItems,uSubMenu);
-
- // Loop through the files and grab the menu items in
- // the ini file. Fills the alloc'd array with the
- // menu items
- for (i=0;i<uMaxItems;i++)
- {
- szTemp[0] = lpitem[i].szFile[0] = '\0';
- wsprintf((LPSTR)szKey,"%s%u",(LPSTR)ITEM_KEY,i+1);
- GetPrivateProfileString ( ITEM_APP, szKey,
- szTemp,szTemp,ITEM_MAXLEN, lpinifile);
- if (*szTemp)
- {
- // Trim default directory off if needed
- ItemListFilenameCleanup(szTemp);
- lstrcpy (lpitem[i].szFile,szTemp);
- upcase (lpitem[i].szFile);
- uCount++;
- }
- }
-
- // Now build the menu
- if (uCount)
- ItemListRestackMenu ( hMenu );
-
- return uCount;
- }
-
- /**********************************************************
- ItemListSave
-
- Save the menu items to the ini file.
-
- Returns the count of the number of menu items saved
- **********************************************************/
- UINT ItemListSave (HMENU hMenu, LPSTR lpinifile )
- {
- UINT uCount = 0;
- UINT i;
- char szKey[20];
-
- for (i=0;i<uMaxItems;i++)
- {
- if (*lpitem[i].szFile)
- {
- wsprintf((LPSTR)szKey,"%s%u",(LPSTR)ITEM_KEY,i+1);
- upcase(lpitem[i].szFile);
- WritePrivateProfileString(ITEM_APP,szKey,
- lpitem[i].szFile,lpinifile);
- uCount++;
- }
- }
-
- return uCount;
- }
-
- /**********************************************************
- ItemListAdd
-
- Add a new menu item to the list. If the menu item is
- already on the list, then force it to the top of the
- list. If it is not already there, then we place it
- on the top and drop the bottom one off.
-
- Returns the queue number where the item was placed.
- If unsuccesful, returns 0.
- **********************************************************/
- UINT ItemListAdd (HMENU hMenu, LPSTR lpentry)
- {
-
- if (lstrlen(lpentry) > ITEM_MAXLEN)
- return 0;
-
- // Remove the directory from the filename
- ItemListFilenameCleanup(lpentry);
-
- upcase(lpentry);
-
- // If it's already there, remove it
- if (ItemListFind(hMenu,lpentry) > 0)
- ItemListRemove ( hMenu, lpentry );
-
- // Now set the menu item in it's place
- return ItemListSet ( hMenu, lpentry, 1 );
- }
-
- /**********************************************************
- ItemListSet
-
- Sets a menu item in a certain position in the menu.
-
- Returns the queue number where the item was placed.
- If unsuccesful, returns 0.
- **********************************************************/
- UINT ItemListSet ( HMENU hMenu, LPSTR lpentry, UINT uItem )
- {
- int i;
-
- if (lstrlen(lpentry) > ITEM_MAXLEN)
- return 0;
-
- if (uItem < 1 || uItem > uMaxItems)
- return 0;
-
- // Remove the directory, if any
- ItemListFilenameCleanup(lpentry);
-
- // Loop from the top copying each string down the array
- // list
- for (i=uMaxItems;i>0;i--)
- lstrcpy (lpitem[i].szFile,lpitem[i-1].szFile);
-
- // Place the new element in the list
- lstrcpy (lpitem[uItem-1].szFile,lpentry);
-
- // Rebuild the menu with the new items
- ItemListRestackMenu(hMenu);
-
- return uItem;
- }
-
- /**********************************************************
- ItemListRemove
-
- Removes a menu item from the list
-
- Returns the queue number of the item that was removed.
- If unsuccesful, returns 0.
- **********************************************************/
- UINT ItemListRemove (HMENU hMenu, LPSTR lpentry)
- {
- UINT i=0;
- UINT uItem;
-
- if (lstrlen(lpentry) > ITEM_MAXLEN)
- return 0;
-
- ItemListFilenameCleanup(lpentry);
-
- upcase(lpentry);
- if ((uItem = ItemListFind(hMenu,lpentry)) ==0)
- return 0;
-
- for (i=uItem;i<=uMaxItems;i++)
- lstrcpy (lpitem[i-1].szFile,lpitem[i].szFile);
-
- lpitem[uMaxItems].szFile[0] = '\0';
-
- ItemListRestackMenu(hMenu);
-
- return uItem;
-
- }
-
- /**********************************************************
- ItemListFind
-
- Finds a string in the menu.
-
- Returns the queue number where the item was found.
- If unsuccesful, returns 0.
- **********************************************************/
- UINT ItemListFind (HMENU hMenu, LPSTR lpentry)
- {
- UINT i;
-
- if (lstrlen(lpentry) > ITEM_MAXLEN)
- return 0;
-
- upcase(lpentry);
- for (i=1;i<=uMaxItems;i++)
- if (lstrcmp(lpitem[i-1].szFile,lpentry)==0)
- return i;
-
- return 0;
- }
-
- /**********************************************************
- ItemListRestackMenu
-
- Rebuilds the menu in its entirety based on the current
- array list.
-
- **********************************************************/
- VOID ItemListRestackMenu ( HMENU hMenu )
- {
- UINT uCount=0, i;
- char szItem[ITEM_MAXLEN];
-
- // Start at the bottom of the menu and remove
- // all menu items up to, and including, the separator.
- for (i=0;i<uMaxItems;i++)
- RemoveMenu ( GetSubMenu(hMenu,uSubMenu), i+ITEM_OFFSET, MF_BYCOMMAND);
- ItemListRemoveSeparator(hMenu);
-
- // Now add the separator to ensure it's always there
- ItemListAddSeparator(hMenu);
-
- // Now recompile the menu
- uCount=0;
- for (i=0;i<uMaxItems;i++)
- {
- if (*lpitem[i].szFile)
- {
- wsprintf((LPSTR)szItem,"&%u. %s",uCount+1,(LPSTR)lpitem[i].szFile);
- AppendMenu ( GetSubMenu(hMenu,uSubMenu), MF_BYCOMMAND | MF_STRING, ITEM_OFFSET+uCount,(LPSTR)szItem);
- uCount++;
- }
- }
-
- if (!uCount)
- ItemListRemoveSeparator(hMenu);
- }
-
- /**********************************************************
- upcase
-
- Converts a string to uppercase
-
- **********************************************************/
- VOID upcase(LPSTR lpszStr)
- {
- while(*lpszStr++ = (char) toupper(*lpszStr));
- }
-
- /**********************************************************
- ItemListAddSeparator
-
- Appends a menu separator to the uSubMenu
-
- Returns the position append to or 0 if unsuccessful.
- **********************************************************/
- UINT ItemListAddSeparator(HMENU hMenu)
- {
- if (!ItemListHasSeparator(hMenu))
- return AppendMenu ( GetSubMenu(hMenu,uSubMenu),
- MF_BYCOMMAND | MF_SEPARATOR, IDM_ITEMLISTSEPARATOR,NULL);
- return 0;
- }
-
- /**********************************************************
- ItemListRemoveSeparator
-
- Removes a menu separator from the uSubMenu
-
- Returns the queue number where the item was removed.
- If unsuccessful, returns 0.
- **********************************************************/
- UINT ItemListRemoveSeparator (HMENU hMenu)
- {
- if (ItemListHasSeparator(hMenu))
- return RemoveMenu(GetSubMenu(hMenu,uSubMenu),
- IDM_ITEMLISTSEPARATOR,MF_BYCOMMAND);
- return 0;
- }
-
- /**********************************************************
- ItemListHasSeparator
-
- Check to see if we have a separator.
-
- Returns TRUE if found, FALSE otherwise.
- **********************************************************/
- BOOL ItemListHasSeparator (HMENU hMenu)
- {
- if (GetMenuState (GetSubMenu(hMenu,uSubMenu),
- IDM_ITEMLISTSEPARATOR, MF_BYCOMMAND)==-1)
- return FALSE;
- return TRUE;
- }
-
- /**********************************************************
- ItemListGetFilename
-
- Returns the filename of the parameter passed.
-
- Returns TRUE if found, FALSE otherwise.
- **********************************************************/
- BOOL ItemListGetFilename ( WPARAM wId, LPSTR lpfilename )
-
- {
- int iIndex = (int)(wId-IDM_ITEMLISTSEPARATOR-1);
- char szTemp[ITEM_MAXLEN];
-
- if (iIndex < 0 || iIndex >= (int)uMaxItems)
- return FALSE;
-
- lstrcpy ( szTemp, lpitem[iIndex].szFile);
- if (*szTemp)
- {
- lstrcpy ( lpfilename, (LPSTR)szTemp);
- return TRUE;
- }
- return FALSE;
- }
-
- /**********************************************************
- ItemListFilenameCleanup
-
- Removes the default directory from the filename. This
- function can be suppressed if the default directory
- is initialized to squash "".
-
- **********************************************************/
- VOID ItemListFilenameCleanup(LPSTR lpfile)
-
- {
- char szTemp[ITEM_MAXLEN];
- UINT i,j,loop;
- char *pdest;
-
- if (*szDefaultDir)
- {
- lstrcpy (szTemp,lpfile);
- pdest = strstr(szTemp,szDefaultDir);
- if (pdest!=NULL)
- {
- loop = lstrlen(szTemp) - lstrlen(szDefaultDir);
- j=0;
- for (i=LOWORD(lstrlen(szDefaultDir))+1;i<LOWORD(lstrlen(szTemp));i++)
- {
- if (szTemp[i] != '\\')
- szTemp[j]=szTemp[i];
- j++;
- }
- szTemp[j]='\0';
-
- }
- lstrcpy (lpfile,szTemp);
- }
-
- }
-